const { exec } = require('child_process')
const fs = require('fs')
const path = require('path')
const util = require('util')
const execPromise = util.promisify(exec)

// 添加 edge-js 用于调用 .NET 方法
let edge = null
try {
  edge = require('electron-edge-js')
} catch (error) {
  console.warn('electron-edge-js 加载失败，将使用备用方法:', error.message)
}

/**
 * 获取系统打印机列表
 */
async function getPrinters() {
  try {
    // Windows 系统使用 wmic 命令获取打印机列表
    const { stdout } = await execPromise('wmic printer get name,default')
    
    // 解析输出
    const lines = stdout.trim().split('\n').slice(1) // 跳过标题行
    const printers = []
    
    for (const line of lines) {
      const match = line.trim().match(/^(TRUE|FALSE)\s+(.+)$/)
      if (match) {
        printers.push({
          name: match[2].trim(),
          isDefault: match[1].trim() === 'TRUE'
        })
      }
    }
    
    return printers
  } catch (error) {
    console.error('获取打印机列表失败:', error)
    throw new Error('获取打印机列表失败')
  }
}

/**
 * 打印文件
 * @param {Object} options 打印选项
 * @param {string} options.filePath 文件路径
 * @param {string} options.printerName 打印机名称
 * @param {boolean} options.duplex 是否双面打印
 * @param {number} options.copies 打印份数
 */
async function print(options) {
  const { filePath, printerName, duplex = false, copies = 1 } = options
  
  if (!fs.existsSync(filePath)) {
    throw new Error(`文件不存在: ${filePath}`)
  }
  
  try {
    const fileExt = path.extname(filePath).toLowerCase()
    
    // 尝试使用 ShellExecute 方法打印（类似于 Python 脚本中的方法）
    try {
      return await printWithShellExecute(filePath, printerName, copies)
    } catch (shellError) {
      console.warn('ShellExecute 打印失败:', shellError.message)
      
      // 如果 ShellExecute 失败，回退到原来的方法
      // 根据文件类型选择不同的打印方法
      if (fileExt === '.pdf') {
        // PDF 文件使用 SumatraPDF
        const appRoot = path.resolve(__dirname, '../../')
        const sumatraPaths = [
          path.join(appRoot, 'resources/SumatraPDF.exe'),
          path.join(appRoot, 'resources/bin/SumatraPDF.exe'),
          'C:\\Program Files\\SumatraPDF\\SumatraPDF.exe',
          'C:\\Program Files (x86)\\SumatraPDF\\SumatraPDF.exe'
        ]
        
        let sumatraPath = null
        for (const p of sumatraPaths) {
          if (fs.existsSync(p)) {
            sumatraPath = p
            break
          }
        }
        
        if (!sumatraPath) {
          throw new Error('找不到 SumatraPDF.exe')
        }
        
        // 构建打印设置
        const settings = []
        if (duplex) settings.push('duplex')
        if (copies > 1) settings.push(`copies=${copies}`)
        const settingsStr = settings.length > 0 ? `-print-settings "${settings.join(',')}"` : ''
        
        // 构建命令
        const command = `"${sumatraPath}" -print-to "${printerName}" ${settingsStr} -silent "${filePath}"`
        console.log(`执行打印命令: ${command}`)
        
        await execPromise(command, { timeout: 60000 }) // 增加超时时间到60秒
        return { message: `成功打印文件: ${path.basename(filePath)}` }
      } else if (['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.txt', '.wps', '.et', '.dps'].includes(fileExt)) {
        // 使用 WPS 打印文档
        return await printWithWPS(filePath, printerName, copies)
      } else {
        // 尝试使用通用方法打印其他类型文件
        return await printGeneric(filePath, printerName)
      }
    }
  } catch (error) {
    console.error('打印文件失败:', error)
    throw new Error(`打印文件失败: ${error.message}`)
  }
}

// 添加 node-windows 模块用于更可靠的 Windows API 调用
let nodeWindows = null;
try {
  nodeWindows = require('node-windows');
} catch (error) {
  console.warn('node-windows 加载失败，将使用备用方法:', error.message);
}

/**
 * 使用 ShellExecute 打印文件（类似于 Python 脚本中的方法）
 * @param {string} filePath 文件路径
 * @param {string} printerName 打印机名称
 * @param {number} copies 打印份数
 */
async function printWithShellExecute(filePath, printerName, copies = 1) {
  // 首先尝试使用 node-windows 模块
  if (nodeWindows && nodeWindows.Shell) {
    try {
      console.log(`使用 node-windows 打印: ${filePath} 到 ${printerName}`);
      
      // 设置默认打印机
      await execPromise(`wmic printer where name="${printerName.replace(/"/g, '\\"')}" call setdefaultprinter`);
      
      // 使用 Shell.execute 打印
      return new Promise((resolve, reject) => {
        nodeWindows.Shell.execute(filePath, 'print', '', (error) => {
          if (error) {
            console.error('node-windows 打印失败:', error);
            reject(new Error(`node-windows 打印失败: ${error.message || error}`));
          } else {
            // 等待打印任务提交
            setTimeout(() => {
              resolve({ message: `成功发送打印请求: ${path.basename(filePath)}` });
            }, 2000);
          }
        });
      });
    } catch (nodeWindowsError) {
      console.warn('node-windows 打印失败:', nodeWindowsError.message);
      // 如果 node-windows 方法失败，继续尝试其他方法
    }
  }
  
  // 如果 edge-js 不可用或失败，使用 PowerShell 调用 ShellExecute
  try {
    // 设置默认打印机
    await execPromise(`wmic printer where name="${printerName.replace(/"/g, '\\"')}" call setdefaultprinter`);
    
    // 使用 PowerShell 调用 ShellExecute
    const psScript = `
      Add-Type -TypeDefinition @"
      using System;
      using System.Runtime.InteropServices;
      
      public class ShellExecuteHelper {
          [DllImport("shell32.dll", CharSet = CharSet.Auto)]
          public static extern IntPtr ShellExecute(
              IntPtr hwnd,
              string lpOperation,
              string lpFile,
              string lpParameters,
              string lpDirectory,
              int nShowCmd);
      }
"@
      
      $result = [ShellExecuteHelper]::ShellExecute(
          [IntPtr]::Zero,
          "print",
          "${filePath.replace(/\\/g, '\\\\')}",
          "",
          ".",
          0
      )
      
      # ShellExecute 返回值大于 32 表示成功
      if ($result.ToInt64() -gt 32) {
          Write-Output "打印请求已发送"
      } else {
          Write-Error "ShellExecute 失败，错误码: $($result.ToInt64())"
          exit 1
      }
    `;
    
    // 创建临时 PowerShell 脚本文件
    const tempPsFile = path.join(require('os').tmpdir(), `print_${Date.now()}.ps1`);
    fs.writeFileSync(tempPsFile, psScript, 'utf8');
    
    // 执行 PowerShell 脚本
    console.log(`执行 PowerShell ShellExecute 打印: ${tempPsFile}`);
    await execPromise(`powershell -ExecutionPolicy Bypass -File "${tempPsFile}"`, { timeout: 30000 });
    
    // 删除临时脚本文件
    try { fs.unlinkSync(tempPsFile); } catch (e) {}
    
    // 等待一段时间，让打印任务有时间提交
    await new Promise(resolve => setTimeout(resolve, 2000));
    
    return { message: `成功发送打印请求: ${path.basename(filePath)}` };
  } catch (psError) {
    console.warn('PowerShell ShellExecute 失败:', psError.message);
    
    // 尝试使用更简单的 PowerShell 命令
    try {
      const simpleCommand = `powershell -Command "Start-Process -FilePath '${filePath}' -Verb Print"`;
      console.log(`尝试简单 PowerShell 打印: ${simpleCommand}`);
      await execPromise(simpleCommand, { timeout: 30000 });
      
      // 等待打印任务提交
      await new Promise(resolve => setTimeout(resolve, 2000));
      
      return { message: `成功发送打印请求: ${path.basename(filePath)}` };
    } catch (simplePsError) {
      console.warn('简单 PowerShell 打印失败:', simplePsError.message);
      throw new Error(`所有 ShellExecute 方法都失败`);
    }
  }
}

/**
 * 使用 WPS 打印文件
 * @param {string} filePath 文件路径
 * @param {string} printerName 打印机名称
 * @param {number} copies 打印份数
 */
async function printWithWPS(filePath, printerName, copies = 1) {
  // WPS 可能的安装路径
  const wpsPaths = [
    // WPS 2019/2021
    "C:\\Users\\Administrator\\AppData\\Local\\kingsoft\\WPS Office\\12.1.0.20784\\office6\\wps.exe",
    // WPS 2016
    "C:\\Program Files\\Kingsoft\\WPS Office\\ksolaunch.exe",
    "C:\\Program Files (x86)\\Kingsoft\\WPS Office\\ksolaunch.exe",
    // WPS 其他版本
    "C:\\Program Files (x86)\\WPS Office\\11.1.0.11664\\office6\\wps.exe",
    // 通过环境变量查找
    path.join(process.env.ProgramFiles || 'C:\\Program Files', 'Kingsoft\\WPS Office\\ksolaunch.exe'),
    path.join(process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)', 'Kingsoft\\WPS Office\\ksolaunch.exe'),
    // 用户目录
    path.join(process.env.USERPROFILE || 'C:\\Users\\Administrator', 'AppData\\Local\\Kingsoft\\WPS Office\\ksolaunch.exe')
  ];
  
  let wpsPath = null;
  for (const p of wpsPaths) {
    if (fs.existsSync(p)) {
      wpsPath = p;
      break;
    }
  }
  
  if (!wpsPath) {
    // 如果找不到 WPS，尝试查找 Office
    const officePaths = [
      "C:\\Program Files\\Microsoft Office\\root\\Office16\\WINWORD.EXE",
      "C:\\Program Files (x86)\\Microsoft Office\\root\\Office16\\WINWORD.EXE",
      "C:\\Program Files\\Microsoft Office\\Office16\\WINWORD.EXE",
      "C:\\Program Files (x86)\\Microsoft Office\\Office16\\WINWORD.EXE"
    ];
    
    for (const p of officePaths) {
      if (fs.existsSync(p)) {
        return await printWithOffice(filePath, printerName, copies, p);
      }
    }
    
    throw new Error("找不到 WPS 或 Office 安装路径");
  }
  
  console.log(`使用 WPS 路径: ${wpsPath}`);
  
  // 尝试直接使用命令行参数打印
  try {
    // 设置默认打印机
    await execPromise(`wmic printer where name="${printerName.replace(/"/g, '\\"')}" call setdefaultprinter`);
    
    // 使用 WPS 的静默打印参数
    const command = `"${wpsPath}" /w "${filePath}" /p /q /n=${copies}`;
    console.log(`尝试静默打印: ${command}`);
    await execPromise(command, { timeout: 60000 });
    return { message: `成功打印文件: ${path.basename(filePath)}` };
  } catch (error) {
    console.warn(`静默打印失败: ${error.message}`);
  }
  
  // 尝试使用 VBS 脚本实现自动打印
  try {
    // 创建临时 VBS 脚本文件
    const tempVbsFile = path.join(require('os').tmpdir(), `print_${Date.now()}.vbs`);
    
    // VBS 脚本内容 - 自动打开文件并打印
    const vbsContent = `
      On Error Resume Next
      
      ' 设置打印机
      Set WshNetwork = WScript.CreateObject("WScript.Network")
      WshNetwork.SetDefaultPrinter "${printerName.replace(/"/g, '""')}"
      
      ' 打开文件并打印
      Set objWord = CreateObject("WPS.Application")
      objWord.Visible = False
      
      ' 打开文件
      Set objDoc = objWord.Documents.Open("${filePath.replace(/\\/g, '\\\\')}")
      
      ' 检查是否成功打开文件
      If Err.Number <> 0 Then
        WScript.Echo "错误：无法打开文件 - " & Err.Description
        WScript.Quit 1
      End If
      
      ' 设置打印份数并打印
      objDoc.PrintOut False, False, 1, 1, "${printerName.replace(/"/g, '""')}", 1, ${copies}, ""
      
      ' 检查打印是否成功
      If Err.Number <> 0 Then
        WScript.Echo "错误：打印失败 - " & Err.Description
        objDoc.Close
        objWord.Quit
        WScript.Quit 1
      End If
      
      ' 关闭文档和应用程序
      objDoc.Close
      objWord.Quit
      
      ' 清理对象
      Set objDoc = Nothing
      Set objWord = Nothing
      Set WshNetwork = Nothing
      
      WScript.Echo "打印成功"
    `;
    
    // 写入 VBS 脚本
    fs.writeFileSync(tempVbsFile, vbsContent, 'utf8');
    
    // 执行 VBS 脚本
    console.log(`执行 VBS 脚本打印: ${tempVbsFile}`);
    const { stdout } = await execPromise(`cscript //nologo "${tempVbsFile}"`, { timeout: 60000 });
    
    // 删除临时脚本文件
    try { fs.unlinkSync(tempVbsFile); } catch (e) {}
    
    if (stdout.includes("打印成功")) {
      return { message: `成功打印文件: ${path.basename(filePath)}` };
    } else {
      throw new Error(stdout || "VBS 脚本执行失败");
    }
  } catch (error) {
    console.warn(`VBS 脚本打印失败: ${error.message}`);
  }
  
  // 如果 VBS 脚本失败，尝试使用 AutoHotkey
  try {
    // 创建临时 AutoHotkey 脚本文件
    const tempAhkFile = path.join(require('os').tmpdir(), `print_${Date.now()}.ahk`);
    const ahkContent = `
      #NoEnv
      #SingleInstance Force
      SetWorkingDir %A_ScriptDir%
      SetTitleMatchMode, 2
      DetectHiddenWindows, On
      
      ; 设置超时时间（毫秒）
      timeout := 60000
      startTime := A_TickCount
      
      ; 运行 WPS 并打开文件
      Run, "${wpsPath}" "${filePath}"
      
      ; 等待 WPS 窗口出现 - 尝试多种可能的窗口标题
      FileAppend, 等待 WPS 窗口出现...\n, *
      Loop, 10
      {
        ; 尝试多种可能的窗口标题
        WinWait, ${path.basename(filePath)} - WPS,, 2
        if !ErrorLevel
          break
          
        WinWait, ${path.basename(filePath)},, 2
        if !ErrorLevel
          break
          
        WinWait, ahk_exe wps.exe,, 2
        if !ErrorLevel
          break
          
        WinWait, ahk_exe ksolaunch.exe,, 2
        if !ErrorLevel
          break
          
        if (A_Index = 10) {
          FileAppend, 错误：无法找到 WPS 窗口\n, *
          ExitApp, 1
        }
        
        Sleep, 1000
      }
      
      FileAppend, WPS 窗口已找到，等待加载完成...\n, *
      
      ; 等待 WPS 完全加载
      Sleep, 3000
      
      ; 按下 Ctrl+P 打开打印对话框
      WinActivate
      Send, ^p
      Sleep, 2000
      
      ; 等待打印对话框出现 - 尝试多种可能的对话框标题
      FileAppend, 等待打印对话框出现...\n, *
      Loop, 5
      {
        WinWait, 打印,, 2
        if !ErrorLevel
          break
          
        WinWait, Print,, 2
        if !ErrorLevel
          break
          
        WinWait, ahk_class #32770,, 2
        if !ErrorLevel
          break
          
        if (A_Index = 5) {
          FileAppend, 错误：无法打开打印对话框，尝试使用菜单\n, *
          
          ; 尝试使用菜单
          WinActivate
          Send, !f
          Sleep, 500
          Send, p
          Sleep, 1000
          
          ; 再次等待打印对话框
          WinWait, 打印,, 3
          if ErrorLevel {
            WinWait, Print,, 3
            if ErrorLevel {
              FileAppend, 错误：无法通过菜单打开打印对话框\n, *
              WinClose, ${path.basename(filePath)}
              ExitApp, 1
            }
          }
        }
      }
      
      FileAppend, 打印对话框已找到，设置打印机...\n, *
      
      ; 选择打印机 - 尝试多种可能的快捷键
      Sleep, 1000
      Send, !p
      Sleep, 500
      Send, ${printerName}
      Sleep, 500
      
      ; 设置打印份数
      Send, !c
      Sleep, 300
      Send, ${copies}
      Sleep, 500
      
      ; 点击打印按钮 - 尝试多种可能的快捷键
      Send, !p
      Sleep, 500
      
      ; 如果上面的快捷键不起作用，尝试 Enter 键
      if WinExist("打印") || WinExist("Print") {
        Send, {Enter}
        Sleep, 500
      }
      
      ; 等待打印完成
      Sleep, 5000
      
      ; 关闭 WPS
      WinClose, ${path.basename(filePath)}
      
      FileAppend, 打印成功\n, *
      ExitApp, 0
    `;
    
    // 写入 AutoHotkey 脚本
    fs.writeFileSync(tempAhkFile, ahkContent, 'utf8');
    
    // 检查是否安装了 AutoHotkey
    const ahkPaths = [
      "C:\\Program Files\\AutoHotkey\\AutoHotkey.exe",
      "C:\\Program Files (x86)\\AutoHotkey\\AutoHotkey.exe",
      "D:\\AUTOHOTKEY\\v2\\AutoHotkey.exe",
      path.join(require('os').tmpdir(), 'AutoHotkey.exe')
    ];
    
    let ahkPath = null;
    for (const p of ahkPaths) {
      if (fs.existsSync(p)) {
        ahkPath = p;
        break;
      }
    }
    
    // 如果没有找到 AutoHotkey，尝试下载便携版
    if (!ahkPath) {
      const ahkDownloadUrl = "https://www.autohotkey.com/download/ahk.zip";
      const ahkZipPath = path.join(require('os').tmpdir(), 'ahk.zip');
      const ahkExtractPath = path.join(require('os').tmpdir());
      
      console.log("未找到 AutoHotkey，尝试下载便携版...");
      
      // 使用 PowerShell 下载 AutoHotkey
      try {
        const downloadCmd = `powershell -Command "(New-Object Net.WebClient).DownloadFile('${ahkDownloadUrl}', '${ahkZipPath}')"`;
        await execPromise(downloadCmd, { timeout: 60000 });
        
        // 解压 AutoHotkey
        const extractCmd = `powershell -Command "Expand-Archive -Path '${ahkZipPath}' -DestinationPath '${ahkExtractPath}' -Force"`;
        await execPromise(extractCmd, { timeout: 60000 });
        
        ahkPath = path.join(ahkExtractPath, 'AutoHotkey.exe');
        
        if (!fs.existsSync(ahkPath)) {
          throw new Error("无法找到解压后的 AutoHotkey.exe");
        }
      } catch (error) {
        console.warn(`下载 AutoHotkey 失败: ${error.message}`);
        throw new Error("无法下载 AutoHotkey，请手动安装");
      }
    }
    
    // 执行 AutoHotkey 脚本
    console.log(`执行 AutoHotkey 脚本打印: ${tempAhkFile}`);
    const { stdout: ahkOutput } = await execPromise(`"${ahkPath}" "${tempAhkFile}"`, { timeout: 120000 });
    
    // 删除临时脚本文件
    try { fs.unlinkSync(tempAhkFile); } catch (e) {}
    
    console.log(`AutoHotkey 输出: ${ahkOutput}`);
    
    if (ahkOutput.includes("打印成功")) {
      return { message: `成功打印文件: ${path.basename(filePath)}` };
    } else {
      throw new Error(ahkOutput || "AutoHotkey 脚本执行失败");
    }
  } catch (error) {
    console.warn(`AutoHotkey 打印失败: ${error.message}`);
  }
  
  // 如果上述方法都失败，尝试使用命令行参数
  return await fallbackPrintMethods(wpsPath, filePath, printerName, copies);
}

/**
 * 将文件转换为 PDF
 * @param {string} filePath 源文件路径
 * @returns {Promise<string|null>} 转换后的 PDF 文件路径，失败返回 null
 */
async function convertToPdf(filePath) {
  const fileExt = path.extname(filePath).toLowerCase();
  const fileName = path.basename(filePath, fileExt);
  const pdfFile = path.join(require('os').tmpdir(), `${fileName}_${Date.now()}.pdf`);
  
  try {
    // 尝试使用 LibreOffice 转换
    const libreOfficePaths = [
      "C:\\Program Files\\LibreOffice\\program\\soffice.exe",
      "C:\\Program Files (x86)\\LibreOffice\\program\\soffice.exe"
    ];
    
    for (const loPath of libreOfficePaths) {
      if (fs.existsSync(loPath)) {
        const command = `"${loPath}" --headless --convert-to pdf --outdir "${path.dirname(pdfFile)}" "${filePath}"`;
        console.log(`执行 LibreOffice 转换命令: ${command}`);
        await execPromise(command, { timeout: 60000 });
        
        // 检查转换后的文件是否存在
        const convertedFile = path.join(path.dirname(pdfFile), `${path.basename(filePath, path.extname(filePath))}.pdf`);
        if (fs.existsSync(convertedFile)) {
          // 重命名为我们需要的文件名
          fs.renameSync(convertedFile, pdfFile);
          return pdfFile;
        }
      }
    }
    
    // 如果 LibreOffice 转换失败，尝试使用 WPS 命令行转换
    const wpsPaths = [
      "C:\\Users\\Administrator\\AppData\\Local\\kingsoft\\WPS Office\\12.1.0.20784\\office6\\wps.exe",
      "C:\\Program Files\\Kingsoft\\WPS Office\\ksolaunch.exe",
      "C:\\Program Files (x86)\\Kingsoft\\WPS Office\\ksolaunch.exe"
    ];
    
    for (const wpsPath of wpsPaths) {
      if (fs.existsSync(wpsPath)) {
        // WPS 没有直接的命令行转换参数，我们可以尝试使用 VBS 脚本
        const tempVbsFile = path.join(require('os').tmpdir(), `convert_${Date.now()}.vbs`);
        
        const vbsContent = `
          On Error Resume Next
          
          ' 打开文件并转换为 PDF
          Set objWord = CreateObject("WPS.Application")
          objWord.Visible = False
          
          ' 打开文件
          Set objDoc = objWord.Documents.Open("${filePath.replace(/\\/g, '\\\\')}")
          
          ' 保存为 PDF
          objDoc.SaveAs2 "${pdfFile.replace(/\\/g, '\\\\')}", 17 ' 17 是 PDF 格式
          
          ' 关闭文档和应用程序
          objDoc.Close
          objWord.Quit
          
          ' 清理对象
          Set objDoc = Nothing
          Set objWord = Nothing
        `;
        
        // 写入 VBS 脚本
        fs.writeFileSync(tempVbsFile, vbsContent, 'utf8');
        
        // 执行 VBS 脚本
        console.log(`执行 VBS 脚本转换: ${tempVbsFile}`);
        await execPromise(`cscript //nologo "${tempVbsFile}"`, { timeout: 60000 });
        
        // 删除临时脚本文件
        try { fs.unlinkSync(tempVbsFile); } catch (e) {}
        
        // 检查转换后的文件是否存在
        if (fs.existsSync(pdfFile)) {
          return pdfFile;
        }
      }
    }
    
    return null;
  } catch (error) {
    console.error('转换 PDF 失败:', error);
    return null;
  }
}

/**
 * 回退到其他打印方法
 * @param {string} wpsPath WPS 可执行文件路径
 * @param {string} filePath 文件路径
 * @param {string} printerName 打印机名称
 * @param {number} copies 打印份数
 */
async function fallbackPrintMethods(wpsPath, filePath, printerName, copies) {
  const errors = [];
  
  // 方法1: 使用 /print 参数
  try {
    const escapedPrinterName = printerName.replace(/"/g, '\\"');
    const command1 = `"${wpsPath}" /print "${filePath}" "${escapedPrinterName}"`;
    console.log(`尝试方法1: ${command1}`);
    await execPromise(command1, { timeout: 60000 });
    return { message: `成功打印文件: ${path.basename(filePath)}` };
  } catch (error) {
    errors.push(`方法1失败: ${error.message}`);
  }
  
  // 方法2: 先设置默认打印机，然后使用 /p 参数
  try {
    // 保存当前默认打印机
    const { stdout: currentDefault } = await execPromise('wmic printer where default=true get name');
    let currentDefaultPrinter = '';
    const lines = currentDefault.trim().split('\n');
    if (lines.length > 1 && lines[1]) {
      currentDefaultPrinter = lines[1].trim();
    }
    
    // 设置临时默认打印机
    await execPromise(`wmic printer where name="${printerName.replace(/"/g, '\\"')}" call setdefaultprinter`);
    
    // 使用简单的 /p 参数打印
    const command2 = `"${wpsPath}" /p "${filePath}"`;
    console.log(`尝试方法2: ${command2}`);
    await execPromise(command2, { timeout: 60000 });
    
    // 恢复原来的默认打印机
    if (currentDefaultPrinter) {
      await execPromise(`wmic printer where name="${currentDefaultPrinter.replace(/"/g, '\\"')}" call setdefaultprinter`);
    }
    
    return { message: `成功打印文件: ${path.basename(filePath)}` };
  } catch (error) {
    errors.push(`方法2失败: ${error.message}`);
  }
  
  // 方法3: 使用 Windows 自带的打印命令
  try {
    const command3 = `rundll32.exe mshtml.dll,PrintHTML "${filePath}"`;
    console.log(`尝试方法3: ${command3}`);
    await execPromise(command3, { timeout: 60000 });
    return { message: `成功打印文件: ${path.basename(filePath)}` };
  } catch (error) {
    errors.push(`方法3失败: ${error.message}`);
  }
  
  // 方法4: 使用 ShellExecute 打印
  try {
    const command4 = `powershell -Command "Start-Process -FilePath '${filePath}' -Verb Print"`;
    console.log(`尝试方法4: ${command4}`);
    await execPromise(command4, { timeout: 60000 });
    return { message: `成功打印文件: ${path.basename(filePath)}` };
  } catch (error) {
    errors.push(`方法4失败: ${error.message}`);
  }
  
  // 所有方法都失败
  throw new Error(`打印失败: ${errors.join('; ')}`);
}

/**
 * 使用 Office 打印文件
 * @param {string} filePath 文件路径
 * @param {string} printerName 打印机名称
 * @param {number} copies 打印份数
 * @param {string} officePath Office 可执行文件路径
 */
async function printWithOffice(filePath, printerName, copies, officePath) {
  try {
    // 设置默认打印机
    await execPromise(`wmic printer where name="${printerName.replace(/"/g, '\\"')}" call setdefaultprinter`);
    
    // 使用 Office 打印
    const command = `"${officePath}" /q /n /p "${filePath}"`;
    console.log(`使用 Office 打印: ${command}`);
    await execPromise(command, { timeout: 60000 });
    
    return { message: `成功使用 Office 打印文件: ${path.basename(filePath)}` };
  } catch (error) {
    console.error('Office 打印失败:', error);
    throw new Error(`Office 打印失败: ${error.message}`);
  }
}

/**
 * 通用打印方法
 * @param {string} filePath 文件路径
 * @param {string} printerName 打印机名称
 */
async function printGeneric(filePath, printerName) {
  try {
    // 设置默认打印机
    await execPromise(`wmic printer where name="${printerName.replace(/"/g, '\\"')}" call setdefaultprinter`);
    
    // 使用 Windows 默认程序打印
    const command = `powershell -Command "Start-Process -FilePath '${filePath}' -Verb Print"`;
    console.log(`使用通用方法打印: ${command}`);
    await execPromise(command, { timeout: 60000 });
    
    return { message: `成功打印文件: ${path.basename(filePath)}` };
  } catch (error) {
    console.error('通用打印方法失败:', error);
    throw new Error(`通用打印方法失败: ${error.message}`);
  }
}

/**
 * 批量打印文件
 * @param {Object} options 打印选项
 * @param {Array<string>} options.filePaths 文件路径数组
 * @param {string} options.printerName 打印机名称
 * @param {boolean} options.duplex 是否双面打印
 * @param {number} options.copies 打印份数
 */
async function batchPrint(options) {
  const { filePaths, printerName, duplex = false, copies = 1 } = options;
  
  if (!Array.isArray(filePaths) || filePaths.length === 0) {
    throw new Error('文件列表为空');
  }
  
  const results = [];
  let successCount = 0;
  
  for (let i = 0; i < filePaths.length; i++) {
    const filePath = filePaths[i];
    console.log(`正在打印 ${i+1}/${filePaths.length}: ${path.basename(filePath)}`);
    
    try {
      const result = await print({ filePath, printerName, duplex, copies });
      results.push({
        file: path.basename(filePath),
        success: true,
        message: result.message
      });
      successCount++;
    } catch (error) {
      results.push({
        file: path.basename(filePath),
        success: false,
        error: error.message
      });
    }
  }
  
  return {
    message: `打印完成: ${successCount}/${filePaths.length} 个文件成功`,
    details: {
      total: filePaths.length,
      success: successCount,
      failed: filePaths.length - successCount,
      results
    }
  };
}

/**
 * 测试打印机
 * @param {string} printerName 打印机名称
 */
async function testPrinter(printerName) {
  // 创建一个临时文本文件
  const tempFile = path.join(require('os').tmpdir(), 'printer_test.txt');
  
  try {
    // 写入测试内容
    fs.writeFileSync(tempFile, `打印机测试页\n打印机: ${printerName}\n时间: ${new Date().toLocaleString()}\n如果您看到此页面，说明打印机工作正常。`, 'utf8');
    
    // 打印测试文件
    const result = await print({
      filePath: tempFile,
      printerName,
      duplex: false,
      copies: 1
    });
    
    // 删除临时文件
    try { fs.unlinkSync(tempFile); } catch (e) {}
    
    return result;
  } catch (error) {
    // 尝试删除临时文件
    try { fs.unlinkSync(tempFile); } catch (e) {}
    throw error;
  }
}

/**
 * 获取系统信息
 */
async function getSystemInfo() {
  try {
    // 获取默认打印机
    let defaultPrinter = '未知';
    try {
      const { stdout } = await execPromise('wmic printer where default=true get name');
      const lines = stdout.trim().split('\n');
      if (lines.length > 1) {
        defaultPrinter = lines[1].trim();
      }
    } catch (e) {
      console.warn('获取默认打印机失败:', e);
    }
    
    return {
      success: true,
      os: process.platform,
      architecture: process.arch,
      default_printer: defaultPrinter
    };
  } catch (error) {
    console.error('获取系统信息失败:', error);
    throw new Error(`获取系统信息失败: ${error.message}`);
  }
}

// 确保导出所有需要的函数
module.exports = {
  getPrinters,
  print,
  printWithWPS,
  printWithOffice,
  printGeneric,
  batchPrint,
  testPrinter,
  getSystemInfo,
  convertToPdf
}